<!-- <template>
    <div class="maintenancePlanAdd">
        <div class="panel-body">
            <div class="demo">
                <canvas id="canvas" :width="width" :height="height" />
                <div class="draw-btn-group" v-show="!readstate">
                    <div>
                        <button size="mini" type="primary" style="width: 80px !important;" @click="uploadImgConfirm">
                            图片上传
                        </button>
                        <button size="mini" type="danger" @click="clean">
                            清除
                        </button>
                    </div>
                    <div>
                        <button v-show="bgImgSrc !== ''" v-for="(item, index) in alarmLevel" :key="index"
                            :style="{ background: colorGrounp[index] }" size="mini" @click="drawPolygon(index)">{{ item }}
                        </button>
                    </div>
                </div>
            </div>
        </div>
        <img id="expImg" :src="bgImgSrc">
        <img id="img" :src="bgImgSrc">
        <input v-show="false" type="file" @change="uploadImgChange" id="imgInput" accept="image/*">
        <p class="tip-title" v-show="bgImgSrc === ''">上传的图片可以进行拖拽调整大小和方向</p>
    </div>
</template>

<script>
import fabric from 'fabric';

export default {
    name: 'FabricView',
    props: ['readstate', 'drawinfo'],
    data() {
        return {
            bgImgFlag: true,
            bgImgSrc: '',
            imgFile: {},
            width: 800,
            height: 400,
            alarmLevel: ['一级风险', '二级风险', '三级风险', '四级风险'],
            colorGrounp: ['rgba(51, 164, 255, 1)', 'rgba(255, 200, 89, 1)', 'rgba(255, 160, 89, 1)', 'rgba(196,43, 1, 1)'],
            colorGrounpFill: ['rgba(51, 164, 255, 0.3)', 'rgba(255, 200, 89, 0.3)', 'rgba(255, 160, 89, 0.3)', 'rgba(196,43, 1, 0.3)'],
            canvas: {},
            mouseFrom: {},
            mouseTo: {},
            drawType: '', // 当前绘制图像ROI
            drawWidth: 2, // 笔触宽度
            drawingObject: null, // 当前绘制对象
            moveCount: 1, // 绘制移动计数器
            doDrawing: false, // 绘制状态
            // polygon 相关参数
            polygonMode: false,
            pointArray: [],
            lineArray: [],
            savePointsGroup: [],
            activeShape: false,
            activeLine: '',
            line: {},
            deleteIconURL: require('@/assets/logo.png')
        };
    },
    watch: {
        drawinfo: {
            handler(n) {
                this.drawinfo = n;
                this.$nextTick(() => {
                    this.loadDraw();
                });
            },
            deep: true
        },
        readstate: {
            handler(n) {
                this.readstate = n;
            },
            deep: true
        },
        width() {
            this.canvas.setWidth(this.width);
        },
        height() {
            this.canvas.setHeight(this.height);
        }
    },
    mounted() {
        this.canvas = new fabric.Canvas('canvas', {
            skipTargetFind: false, // 当为真时，跳过目标检测。目标检测将返回始终未定义。点击选择将无效
            selectable: false, // 为false时，不能选择对象进行修改
            selection: false // 是否可以多个对象为一组
        });
        this.canvas.selectionColor = 'rgba(0,0,0,0.05)';
        this.canvas.on('mouse:down', this.mousedown);
        this.canvas.on('mouse:move', this.mousemove);
        document.onkeydown = e => {
            // 键盘 delect删除所选元素
            if (e.keyCode == 46) {
                this.deleteObj();
            }
            // ctrl+z 删除最近添加的元素
            if (e.keyCode == 90 && e.ctrlKey) {
                this.canvas.remove(
                    this.canvas.getObjects()[this.canvas.getObjects().length - 1]
                );
            }
        };
        this.$nextTick(() => {
            this.loadDraw();
        });
    },
    methods: {
        // 保存当前画布为png图片
        save() {
            var canvas = document.getElementById('canvas');
            var imgData = canvas.toDataURL('png');
            imgData = imgData.replace('image/png', 'image/octet-stream');
            // 下载后的问题名，可自由指定
            var filename = 'drawingboard_' + (new Date()).getTime() + '.' + 'png';
            this.saveFile(imgData, filename);
        },
        saveFile(data, filename) {
            var save_link = document.createElement('a');
            save_link.href = data;
            save_link.download = filename;
            var event = document.createEvent('MouseEvents');
            event.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
            save_link.dispatchEvent(event);
        },
        // 提交绘制内容
        submitDraw() {
            const params = {
                pointInfo: [],
                imgInfo: '',
                img: ''
            };
            this.canvas.toJSON(['alarmLevel', 'isBgImg']).objects.forEach(item => {
                const element = {
                    alarmLevel: item.alarmLevel,
                    pointInfo: ''
                };
                if (item?.points) {
                    element.pointInfo = item.points;
                    params.pointInfo.push(element);
                }
                if (item?.isBgImg) {
                    params.imgInfo = item;
                    params.img = item.src;
                    delete params.imgInfo.src;
                }
            });
            this.$emit('saveDraw', params);
        },
        // 清除画布
        clean() {
            this.$confirm('是否清除图片和标记？', '提示', {
                confirmButtonText: '确定',
                cancelButtonText: '取消',
                type: 'warning'
            }).then(() => {
                this.canvas.clear();
                this.bgImgSrc = '';
                this.bgImgFlag = true;
            });
        },
        // 从已渲染的DOM元素加载图片至canvas
        loadExpImg() {
            const imgElement = document.getElementById('expImg');
            imgElement.onload = () => {
                // eslint-disable-next-line new-cap
                new fabric.Image.fromURL(
                    imgElement.src,
                    img => {
                        img.scale(0.3);
                        img.set({
                            originX: 'center',
                            originY: 'center'
                        }, { crossOrigin: 'anonymous' });
                        img.on('scaling', e => { // 拉伸事件
                            const h = img.scaleY;
                            const w = img.scaleX;
                            if (h !== w || w == h) { // 判断缩放值相等或不相等后执行图片等比缩放
                                if (e.e.movementY == -1 || e.e.movementY == 1) {
                                    img.scale(h);// 缩放
                                } else {
                                    img.scale(w);
                                }
                            }
                        });
                        img.setCoords();
                        img.centeredScaling = true;
                        img.centerTransform = true;
                        this.canvas.add(img);
                        this.canvas.centerObject(img);
                        this.canvas.renderAll();
                    }, {
                    selectable: true,
                    hasControls: true,
                    centeredScaling: false,
                    zIndex: -99,
                    isBgImg: true
                });
            };
        },
        // 上传确认
        uploadImgConfirm() {
            if (this.bgImgSrc !== '') {
                this.$confirm('是否重新上传标记？', '提示', {
                    confirmButtonText: '确定',
                    cancelButtonText: '取消',
                    type: 'warning'
                }).then(() => {
                    this.canvas.clear();
                    this.bgImgFlag = true;
                    document.getElementById('imgInput').click();
                });
            } else {
                document.getElementById('imgInput').click();
            }
        },
        // 从文件加载图片至canvas
        uploadImgChange() {
            // 获取文件
            var eleImportInput = document.getElementById('imgInput');
            this.imgFile = eleImportInput.files[0];
            var imgTitle = '';
            // 从reader中获取选择文件的src
            if (/\.(jpe?g|png|gif)$/i.test(this.imgFile.name)) {
                var reader = new FileReader();
                var _this = this;
                reader.addEventListener(
                    'load',
                    function () {
                        imgTitle = _this.imgFile.name;
                        _this.bgImgSrc = this.result;
                    },
                    false
                );
                reader.readAsDataURL(this.imgFile);
            }
            this.loadExpImg();
        },
        // 鼠标按下时触发
        mousedown(e) {
            if (undefined === e) return;
            // 记录鼠标按下时的坐标
            var xy = e.pointer || this.transformMouse(e.e.offsetX, e.e.offsetY);
            this.mouseFrom.x = xy.x;
            this.mouseFrom.y = xy.y;
            this.doDrawing = true;

            this.canvas.skipTargetFind = false;
            try {
                // 此段为判断是否闭合多边形，点击红点时闭合多边形
                if (this.pointArray.length > 1) {
                    // e.target.id == this.pointArray[0].id 表示点击了初始红点
                    if (e.target && e.target.id == this.pointArray[0].id) {
                        this.generatePolygon();
                        return;
                    }
                }
                // 未点击红点则继续作画
                if (this.polygonMode && this.pointArray.length < 4) {
                    this.addPoint(e);
                } else if (this.polygonMode && this.pointArray.length > 0) {
                    this.$message.warning('最多设置四个点');
                }
            } catch (error) {
                console.log(error);
            }
        },
        // 鼠标松开执行
        mouseup(e) {
            if (undefined === e) return;
            var xy = e.pointer || this.transformMouse(e.e.offsetX, e.e.offsetY);
            this.mouseTo.x = xy.x;
            this.mouseTo.y = xy.y;
            this.drawingObject = null;
            this.moveCount = 1;
        },
        // 鼠标移动过程中已经完成了绘制
        mousemove(e) {
            if (undefined === e) return;
            if (this.moveCount % 2 && !this.doDrawing) {
                // 减少绘制频率
                return;
            }
            this.moveCount++;
            var xy = e.pointer || this.transformMouse(e.e.offsetX, e.e.offsetY);
            this.mouseTo.x = xy.x;
            this.mouseTo.y = xy.y;
            if (this.activeLine && this.activeLine.class == 'line') {
                var pointer = this.canvas.getPointer(e.e);
                this.activeLine.set({
                    x2: pointer.x,
                    y2: pointer.y
                });
                var points = this.activeShape.get('points');
                points[this.pointArray.length] = {
                    x: pointer.x,
                    y: pointer.y,
                    zIndex: 1
                };
                this.activeShape.set({
                    points: points
                });
                this.canvas.renderAll();
            }
            this.canvas.renderAll();
        },
        deleteObj() {
            this.canvas.getActiveObjects().map(item => {
                this.canvas.remove(item);
            });
        },
        transformMouse(mouseX, mouseY) {
            return {
                x: mouseX / 1,
                y: mouseY / 1
            };
        },
        // 绘制多边形开始
        drawPolygon(data) {
            if (this.bgImgFlag) {
                this.canvas.getObjects().forEach(obj => {
                    if (obj.isBgImg) {
                        obj.hasControls = false;
                        obj.selectable = false;
                        obj.evented = false;
                    }
                });
                this.bgImgFlag = false;
                this.canvas.renderAll();
            }
            this.drawType = data;
            this.polygonMode = true;
            this.pointArray = []; // 顶点集合
            this.lineArray = []; // 线集合
            this.canvas.isDrawingMode = false;
        },
        addPoint(e) {
            var random = Math.floor(Math.random() * 10000);
            var id = new Date().getTime() + random;
            var circle = new fabric.Circle({
                radius: 5,
                fill: '#ffffff',
                stroke: '#333333',
                strokeWidth: 0.5,
                left: (e.pointer.x || e.e.layerX) / this.canvas.getZoom(),
                top: (e.pointer.y || e.e.layerY) / this.canvas.getZoom(),
                selectable: false,
                hasBorders: false,
                hasControls: false,
                originX: 'center',
                originY: 'center',
                id: id,
                objectCaching: false
            });
            if (this.pointArray.length == 0) {
                circle.set({
                    fill: this.colorGrounp[this.drawType]
                });
            }
            var points = [
                (e.pointer.x || e.e.layerX) / this.canvas.getZoom(),
                (e.pointer.y || e.e.layerY) / this.canvas.getZoom(),
                (e.pointer.x || e.e.layerX) / this.canvas.getZoom(),
                (e.pointer.y || e.e.layerY) / this.canvas.getZoom()
            ];
            this.line = new fabric.Line(points, {
                strokeWidth: 2,
                fill: this.colorGrounp[this.drawType],
                stroke: this.colorGrounp[this.drawType],
                class: 'line',
                originX: 'center',
                originY: 'center',
                selectable: false,
                hasBorders: false,
                hasControls: false,
                evented: false,
                objectCaching: false
            });
            if (this.activeShape) {
                var pos = this.canvas.getPointer(e.e);
                var points = this.activeShape.get('points');
                points.push({
                    x: pos.x,
                    y: pos.y
                });
                var polygon = new fabric.Polygon(points, {
                    stroke: '#333333',
                    strokeWidth: 1,
                    fill: this.colorGrounpFill[this.drawType],
                    opacity: 0.3,
                    selectable: false,
                    hasBorders: false,
                    hasControls: false,
                    evented: false,
                    objectCaching: false
                });
                this.canvas.remove(this.activeShape);
                this.canvas.add(polygon);
                this.activeShape = polygon;
                this.canvas.renderAll();
            } else {
                var polyPoint = [
                    {
                        x: (e.pointer.x || e.e.layerX) / this.canvas.getZoom(),
                        y: (e.pointer.y || e.e.layerY) / this.canvas.getZoom()
                    }
                ];
                var polygon = new fabric.Polygon(polyPoint, {
                    stroke: '#333333',
                    strokeWidth: 1,
                    fill: '#cccccc',
                    opacity: 0.3,
                    selectable: false,
                    hasBorders: false,
                    hasControls: false,
                    evented: false,
                    objectCaching: false
                });
                this.activeShape = polygon;
                this.canvas.add(polygon);
            }
            this.activeLine = this.line;
            this.pointArray.push(circle);
            this.lineArray.push(this.line);
            this.canvas.add(this.line);
            this.canvas.add(circle);
        },
        generatePolygon() {
            var points = [];
            this.pointArray.map((point, index) => {
                points.push({
                    x: point.left,
                    y: point.top
                });
                this.canvas.remove(point);
            });
            this.lineArray.map((line, index) => {
                this.canvas.remove(line);
            });
            this.canvas.remove(this.activeShape).remove(this.activeLine);
            var polygon = new fabric.Polygon(points, {
                stroke: this.colorGrounp[this.drawType],
                strokeWidth: this.drawWidth,
                fill: this.colorGrounpFill[this.drawType],
                opacity: 1,
                selectable: false,
                hasBorders: false,
                hasControls: false,
                alarmLevel: this.drawType
            });
            let max = 0;
            for (let i = 1; i < this.canvas._objects.length; i++) {
                if (this.canvas._objects[i].index > max) max = this.canvas._objects[i].index;
            }
            polygon.index = max + 1;
            this.canvas.add(polygon);
            this.activeLine = null;
            this.activeShape = null;
            this.polygonMode = false;
            this.doDrawing = false;
            // this.drawType = null;
            fabric.Image.fromURL(this.deleteIconURL, this.deletecallback);
        },
        // 从画布中删除当前选中的对象
        deleteObject() {
            const activeObject = this.canvas.getActiveObject();
            if (activeObject) {
                this.canvas._objects.forEach(item => {
                    if (item.index === activeObject.index) {
                        this.canvas.remove(item);
                    }
                });
                this.canvas.remove(activeObject);
                this.canvas.renderAll();
            }
        },
        // 渲染删除按钮
        async deletecallback(img) {
            const self = this;
            let max = 0;
            for (let i = 1; i < this.canvas._objects.length; i++) {
                if (this.canvas._objects[i].index > max) max = this.canvas._objects[i].index;
            }
            img.index = max;
            const oImg = await img.set({
                left: this.pointArray[0].left - 20,
                top: this.pointArray[0].top - 20,
                width: 40,
                height: 40,
                angle: 0
            }).scale(0.8);
            this.canvas.add(oImg).renderAll();
            this.canvas.setActiveObject(oImg);
            oImg.on('mousedown', function () {
                self.deleteObject();
            });
        },
        // 回显详情信息
        loadDraw() {
            const self = this;
            if (self.drawinfo.id === '') return;
            const pointGroup = JSON.parse(self.drawinfo.pointInfo);
            const imgInfo = JSON.parse(self.drawinfo.imgInfo);
            self.bgImgSrc = self.drawinfo.img;
            imgInfo.src = self.drawinfo.img;
            // 1、加载底图
            fabric.util.enlivenObjects([imgInfo], objects => {
                objects.forEach(o => {
                    o.selectable = false;
                    o.hasControls = false;
                    o.centeredScaling = false;
                    this.canvas.add(o);
                });
                // 2、处理多边形绘制回显操作
                pointGroup.forEach(async (item, index) => {
                    if (item.pointInfo !== '') {
                        const polygon = new fabric.Polygon(item.pointInfo, {
                            stroke: self.colorGrounp[item.alarmLevel],
                            strokeWidth: self.drawWidth,
                            fill: self.colorGrounpFill[item.alarmLevel],
                            opacity: 1,
                            selectable: false,
                            hasBorders: false,
                            hasControls: false,
                            alarmLevel: item.alarmLevel
                        });
                        polygon.index = index;
                        self.canvas.add(polygon);
                        self.activeLine = null;
                        self.activeShape = null;
                        self.polygonMode = false;
                        self.doDrawing = false;
                        if (!self.readstate) {
                            fabric.Image.fromURL(self.deleteIconURL, async img => {
                                const _self = this;
                                img.index = index;
                                const oImg = await img.set({
                                    left: item.pointInfo[0].x - 20,
                                    top: item.pointInfo[0].y - 20,
                                    width: 40,
                                    height: 40,
                                    angle: 0
                                }).scale(0.8);
                                this.canvas.add(oImg);
                                oImg.on('mousedown', function () {
                                    _self.deleteObject();
                                });
                            });
                        }
                    }
                });
            });
            self.canvas.renderAll();
        }
    }
};
</script>
   
<style scoped>
img {
    display: none;
}

.demo {
    display: flex;
    flex-direction: column;
    align-items: center;
}

canvas {
    border: 1px dashed #2695F9;
}

.draw-btn-group {
    width: 100%;
    margin-top: 10px;
    display: flex;
    align-items: center;
    justify-content: space-between;
}

.draw-btn-group .button {
    color: #ffffff;
}

.tip-title {
    top: 40%;
    left: 33%;
    position: absolute;
    font-size: 16px;
    color: #C2C7CC;
    margin: 0;
}
</style> -->


<template>
    <div>
        <!-- <vue-fabric ref="canvas" :width="width" :height="height"></vue-fabric> -->
    </div>
</template>

<script>
export default {
    name: 'FabricView',
    data() {
        return {
            width: 400,
            height: 600,
        }
    },
    methods: {

    }
}
</script>
